import fs from 'fs';
import path from 'path';
import process from 'process';
import { spawn, exec } from 'child_process';

export class Gener {
    private stepCallBack!: (step: number) => void;
    private _steps = 5;
    public onStep(fn: (step: number) => void) {
        this.stepCallBack = fn;
    }
    public getSteps() {
        return this._steps;
    }
    public async createProject() {
        try {
            this.stepCallBack(1);
            await this.mkSrc();
            this.stepCallBack(2);
            await this.initNpm();
            this.stepCallBack(3);
            await this.installDependens();
            this.stepCallBack(4);
            this.initTsc();
            this.stepCallBack(5);
            this.initGulp();
        } catch (error) {
            console.error(error);
        }
    }
    mkSrc() {
        return new Promise<void>((resolve, reject) => {
            fs.mkdir(path.join(process.cwd(), 'src'), (err) => {
                if (err) {
                    resolve();
                }
                resolve();
            });
        });
    }
    initNpm() {
        return new Promise<void>((resolve, reject) => {
            const npm = spawn('npm', ['init', '-y']);
            npm.stdout.on('data', (data) => {
            })
            npm.stderr.on('data', (data) => {
                reject();
            });
            npm.on('close', (code) => {
                resolve();
            });
        });
    }
    installDependens() {
        return new Promise<void>((resolve, reject) => {
            const com = exec('npm i typescript gulp gulp-cli gulp-sourcemaps gulp-typescript -D', (error, stdout, stderr) => {
                if (error) {
                    reject(error);
                }
            });
            com.on('close', (code) => {
                resolve();
            });
        });
    }
    initTsc() {
    }
    initGulp() {
        const gulpFileContent = `const { src, dest, watch } = require("gulp");
        const ts = require("gulp-typescript");
        const sourcemaps = require("gulp-sourcemaps");
        
        const tsProject = ts.createProject("tsconfig.json");
        
        function build() {
            const tsResult = tsProject
                .src() // or tsProject.src()
                .pipe(tsProject());
            return tsResult.js.pipe(dest("dist"));
        }
        function buildDev(){
            tsProject
                .src()
                .pipe(sourcemaps.init())
                .pipe(tsProject())
                .pipe(sourcemaps.write("."))
                .pipe(dest("dist"));
        }
        function dev(cb) {
            buildDev();
            watch(["src/**/*.ts"], function (cb) {
                buildDev();
                cb();
            });
            cb();
        }
        exports.dev = dev;
        exports.default = build;
        `;
        const gulpfilePath = path.join(process.cwd(), 'gulpfile.js');
        fs.writeFileSync(gulpfilePath, gulpFileContent);
    }
}